
struct LearnerSprite
{
    LearnerSprite() {}
    LearnerSprite(int _frameIndex, int _spriteIndex)
    {
        frameIndex = _frameIndex;
        spriteIndex = _spriteIndex;
    }
    int frameIndex;
    int spriteIndex;
};

class GameModel;

class ModelLearner
{
public:
    void LearnModel(const ReplayCollection &replays, const GameModelParameters &parameters, GameModel &model);
    
private:
    void InitFrames(const ReplayCollection &replays);

    void InitSpriteInstances();

    void MakeGeneralFeatures();

    void InitializeDatasets();

    void TrainDecisionTrees(GameModel &model);
    void TrainVariableTrees(GameModel &model);
    void TrainSpriteTrees(GameModel &model);

    void ComputeVariableChanges(int variableIndex, set<int> &absolutes, set<int> &relatives);

    const LearnerSprite& SampleRandomSprite(int spriteIndex);
    
    Game* _game;
    GameModelParameters _parameters;
    
    LearnerDataset _variableDataset;
    LearnerDataset _spriteDataset;

    vector< unique_ptr<GameModelFrame> > _frames;
    vector< vector<LearnerSprite> > _spriteInstances;
};
